package com.colorlight.cloud.gateway.core.message.event.manager;


import com.colorlight.cloud.common.exception.ParameterException;
import com.colorlight.cloud.gateway.api.message.process.ProcessMessageEventHandler;
import com.colorlight.cloud.mqtt.base.core.utils.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.util.HashMap;
import java.util.Map;

import static com.colorlight.cloud.gateway.core.model.GatewayCoreExceptionEnum.PROCESS_MESSAGE_EVENT_HANDLER_IS_NULL;

/**
 * @author Demon
 */
@Slf4j
@Component
public class ProcessMessageEventHandlerManager implements InitializingBean {
	/**
	 * 必须提前注入
	 */
	private final SpringUtils springUtils;
	private Map<String, ProcessMessageEventHandler<?>> map;
	
	public ProcessMessageEventHandlerManager(SpringUtils springUtils) {
		this.springUtils = springUtils;
	}
	
	@Override
	public void afterPropertiesSet() {
		Map<String, ProcessMessageEventHandler> beansByType;
		beansByType = SpringUtils.getBeansByType(ProcessMessageEventHandler.class);
		map = new HashMap<>(beansByType.size());
		for (ProcessMessageEventHandler<?> processMessageEventHandler : beansByType.values()) {
			map.put(processMessageEventHandler.mapKey(), processMessageEventHandler);
			log.debug("key:{}",processMessageEventHandler.mapKey());
		}
	}
	
	private Map<String, ProcessMessageEventHandler<?>> singleMap() {
		return map == null ? new HashMap<>(128) : map;
	}
	
	
	/**
	 * 返回消息对应的handler
	 *
	 * @param mapKey 消息上报组装的key
	 * @author Demon
	 **/
	public ProcessMessageEventHandler<?> getHandler(String mapKey) {
		if (ObjectUtils.isEmpty(mapKey)) {
			throw new ParameterException(PROCESS_MESSAGE_EVENT_HANDLER_IS_NULL);
		}
		String key = mapKey.toLowerCase();
		if (!singleMap().containsKey(key)) {
			return null;
		}
		return singleMap().get(key);
	}
	
	
	/**
	 * 从主题解析出 上报消息信息 然后组装
	 *
	 * @param protocolType    协议名称
	 * @param instructionName 上报消息名称
	 * @author Demon
	 * 返回消息对应的handler 可能为null
	 **/
	public ProcessMessageEventHandler<?> getHandler(String protocolType, String instructionName) {
		String mapKey = protocolType + instructionName;
		return getHandler(mapKey);
	}
}
